// ===================================
// <copyright>
// This file is part of LABSMFController.
//
//    LABSMFController is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    LABSMFController is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with LABSMFController.  If not, see <http://www.gnu.org/licenses/>.
//    Copyright 2011 David Bakker
//
//</copyright>
// <author>David Bakker</author>
// <email>mailto:DavidFBakker@gmail.com</email>
// <created>Saturday, May 07, 2011</created>
// <lastedit>Saturday, May 07, 2011</lastedit>
// ===================================

using System;
using Microsoft.SPOT;
using Microsoft.SPOT.Input;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Media;

// This file contains two classes, TargetButtons and UndoButton.

namespace LABSMFController.UI
{
    /// <summary>
    /// The target buttons on the touch panel.
    /// </summary>
    internal class TargetButtons : UIElement
    {
        private readonly Int32 targetSelected;
        private byte buttonPixels = 80;
        private bool clicked;
        internal Bitmap[] targetImage;
        internal Bitmap[] targetImageClicked;

        /// <summary>
        /// Initiate a new button
        /// </summary>
        /// <param name="targetSelection">
        /// Identifies the button.
        /// </param>		
        internal TargetButtons(Int32 targetSelection)
        {
            try
            {
                lock (this)
                {
                    targetSelected = targetSelection;
                    Height = buttonPixels;
                    Width = buttonPixels;
                    CreateImages(targetSelection);
                }
            }
            catch (Exception ex)
            {
                Debug.Print(ex.Message);
            }
        }

        /// <summary>
        /// Return a String that identifies a target button.
        /// </summary>		
        private Int32 TargetSelection
        {
            get
            {
                lock (this)
                {
                    return targetSelected;
                }
            }
        }

        /// <summary>
        /// Event that executes when a button is touched.
        /// </summary>
        internal event ButtonTouchedHandler onTargetButtonTouch;

        /// <summary>
        /// Get target button images for the normal and clicked states.
        /// </summary>
        /// <param name="imageNumber">
        /// Identifies the image.
        /// </param>		
        private void CreateImages(Int32 imageNumber)
        {
            try
            {
                targetImage = new Bitmap[Targets.numberOfTargetButtons];
                targetImageClicked = new Bitmap[Targets.numberOfTargetButtons];
                targetImage[imageNumber] = Targets.InitializeImage(imageNumber + 1);
                targetImageClicked[imageNumber] = Targets.InitializeImage(imageNumber + 101);
            }
            catch (Exception ex)
            {
                Debug.Print(ex.Message);
            }
        }

        /// <summary>
        /// Invalidate a control to cause it to refresh.
        /// </summary>
        /// <param name="control">
        /// The control to invalidate.
        /// </param>
        private void DoReInvalidate(UIElement control)
        {
            control.Invalidate();
        }

        /// <summary>
        /// Cause the desired image to display on Invalidate.
        /// </summary>
        /// <param name="dc"></param>
        public override void OnRender(DrawingContext dc)
        {
            try
            {
                lock (this)
                {
                    Bitmap currentImage = null;

                    if (clicked)
                    {
                        currentImage = targetImageClicked[TargetSelection];
                        dc.DrawImage(currentImage, 0, 0, 0, 0, buttonPixels, buttonPixels);

                        clicked = false;

                        //this.Dispatcher.BeginInvoke(new DoReInvalidateDelegate(DoReInvalidate), new object[] { this });
                    }
                    else
                    {
                        currentImage = targetImage[TargetSelection];
                        dc.DrawImage(currentImage, 0, 0, 0, 0, buttonPixels, buttonPixels);
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.Print(ex.Message);
            }
        }

        protected override void OnButtonDown(ButtonEventArgs e)
        {
            base.OnButtonDown(e);
        }

        #region Nested type: ButtonTouchedHandler

        /// <summary>
        /// Delegate for the onButtonTouch event.
        /// </summary>
        /// <param name="targetButtonTouched">
        /// Indicates which button was touched.
        /// </param>
        internal delegate void ButtonTouchedHandler(Int32 targetButtonTouched);

        #endregion

        #region Nested type: DoReInvalidateDelegate

        /// <summary>
        /// Delegate to invalidate a control to cause it to refresh.
        /// </summary>
        /// <param name="control">
        /// The control to invalidate.
        /// </param>		
        private delegate void DoReInvalidateDelegate(UIElement control);

        #endregion

        //protected override void OnStylusDown(StylusEventArgs e)
        //{
        //    int StylusX;
        //    int StylusY;

        //    try
        //    {
        //        if (this.IsVisible)
        //        {
        //            e.GetPosition((UIElement)this, out StylusX, out StylusY);

        //            if (!((StylusX < 0) | (StylusY < 0) | (StylusX > this.Width) | (StylusY > this.Height)))
        //            {
        //                // The touch is within the UI element.

        //                if (onTargetButtonTouch != null)
        //                    onTargetButtonTouch(TargetSelection);

        //                lock (this)
        //                {
        //                    clicked = true;
        //                }
        //                Invalidate();
        //            }
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        Debug.Print(ex.Message);
        //    }
        //}
    }


    /// <summary>
    /// The Undo button on the touch panel.
    /// </summary>
    internal class UndoButton : UIElement
    {
        private byte buttonPixels = 64;
        private bool clicked;
        private Bitmap undoImage;
        private Bitmap undoImage_clicked;

        /// <summary>
        /// Find out if a touch is within the button and if so, call a routine to handle it.
        /// </summary>
        /// <param name="e">
        /// </param>
        //protected override void OnStylusDown(StylusEventArgs e)
        //{
        //    int StylusX;
        //    int StylusY;
        //    try
        //    {
        //        if (this.IsVisible)
        //        {
        //            e.GetPosition((UIElement)this, out StylusX, out StylusY);
        //            if (!((StylusX < 0) | (StylusY < 0) | (StylusX > this.Width) | (StylusY > this.Height)))
        //            {
        //                // The touch is within the button.
        //                if (onUndoButtonTouch != null)
        //                    onUndoButtonTouch();
        //                lock (this)
        //                {
        //                    clicked = true;
        //                }
        //                Invalidate();
        //            }
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        Debug.Print(ex.Message);
        //    }
        //}
        /// <summary>
        /// Initiate a new button
        /// </summary>		
        internal UndoButton()
        {
            try
            {
                lock (this)
                {
                    Height = buttonPixels;
                    Width = buttonPixels;
                    CreateImages();
                }
            }
            catch (Exception ex)
            {
                Debug.Print(ex.Message);
            }
        }

        /// <summary>
        /// Event that executes when a button is touched.
        /// </summary>
        internal event ButtonTouchedHandler onUndoButtonTouch;

        /// <summary>
        /// Create Undo button images for the normal and clicked states.
        /// </summary>		
        private void CreateImages()
        {
            try
            {
                //undoImage = Resources.GetBitmap(Resources.BitmapResources.undo64);
                //undoImage_clicked = Resources.GetBitmap(Resources.BitmapResources.undo64_clicked);
            }
            catch (Exception ex)
            {
                Debug.Print(ex.Message);
            }
        }

        /// <summary>
        /// Invalidate a control to cause it to refresh.
        /// </summary>
        /// <param name="control">
        /// The control to invalidate.
        /// </param>
        private void DoReInvalidate(UIElement control)
        {
            control.Invalidate();
        }

        /// <summary>
        /// Cause the desired image to display on Invalidate.
        /// </summary>
        /// <param name="dc"></param>
        public override void OnRender(DrawingContext dc)
        {
            try
            {
                lock (this)
                {
                    Bitmap currentImage = null;

                    if (clicked)
                    {
                        currentImage = undoImage_clicked;
                        clicked = false;
                    }
                    else
                    {
                        currentImage = undoImage;
                    }
                    dc.DrawImage(currentImage, 0, 0, 0, 0, buttonPixels, buttonPixels);
                    //this.Dispatcher.BeginInvoke(new DoReInvalidateDelegate(DoReInvalidate), new object[] { this });
                }
            }
            catch (Exception ex)
            {
                Debug.Print(ex.Message);
            }
        }

        #region Nested type: ButtonTouchedHandler

        /// <summary>
        /// Delegate for the onButtonTouch event.
        /// </summary>		
        internal delegate void ButtonTouchedHandler();

        #endregion

        #region Nested type: DoReInvalidateDelegate

        /// <summary>
        /// Delegate to invalidate a control to cause it to refresh.
        /// </summary>
        /// <param name="control">
        /// The control to invalidate.
        /// </param>		
        private delegate void DoReInvalidateDelegate(UIElement control);

        #endregion
    }
}